<template>
  <div class="driverContent">
    <div class="driverInfo">
      <div class="header">
        <span class="subTitle">驱动信息</span>
        <div>
          <el-button
            v-permission="['driverLibraryManagement:driverLibrary:downloadDriverDefinitionFile']"
            type="primary"
            @click="handleClick('downloadDriveDefinitionFile')"
          >
            下载驱动定义文件
          </el-button>
          <el-button
            v-permission="['driverLibraryManagement:driverLibrary:editDriverDefinitionFile']"
            type="primary"
            @click="handleClick('updateDriveDefinitionFile')"
          >
            修改驱动定义文件
          </el-button>
        </div>
      </div>
      <div class="driverParams">
        <div>适配范围：{{ currentProjectData.compatible }}</div>
        <div>驱动配置参数：通过驱动定义文件查看</div>
      </div>
    </div>
    <div class="driverFile">
      <div class="header">
        <span class="subTitle">驱动模板文件列表</span>
        <el-button
          v-permission="['driverLibraryManagement:driverLibrary:uploadDriverTemplateFile']"
          type="primary"
          @click="handleClick('uploadDriverFile')"
        >
          上传
        </el-button>
        <addDriverFile ref="addDriverFile" @submit="refreshDriverFile" />
      </div>
      <div class="driverFileContent">
        <div class="leftContent">
          <el-table
            ref="myTable"
            highlight-current-row
            :data="currentProjectData.driverFile"
            class="myTable"
            height="100%"
            :header-cell-style="{
              backgroundColor: '#DCDEEC',
              color: '#333',
              fontWeight: 'bold'
            }"
            :cell-style="{ height: '49px' }"
            @row-click="handleRowClick"
          >
            <el-table-column prop="fileName" label="文件名" show-overflow-tooltip>
              <template slot-scope="{ row }">
                <el-input
                  v-show="row.editable"
                  :ref="'fileName' + row.fileId"
                  v-model="row.fileName"
                  autofocus
                  @blur="handleClick('saveFileName', row)"
                >
                  <template slot="append">{{ row.fileType }}</template>
                </el-input>
                <span v-show="!row.editable" class="pointer" @click="handleClick('edit', row)">
                  {{ row.fileName + row.fileType }}
                </span>
              </template>
            </el-table-column>
            <el-table-column prop="fileType" label="文件类型" width="104">
              <template slot-scope="{ row }">
                <template v-if="row.relationTypeId === 27">.h头文件</template>
                <template v-else-if="row.relationTypeId === 28">.c源文件</template>
                <template v-else-if="row.relationTypeId === 30">其他驱动文件</template>
                <template v-else>说明文档</template>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="156">
              <template slot-scope="scope">
                <el-link
                  v-permission="['driverLibraryManagement:driverLibrary:editDriverTemplateFile']"
                  type="primary"
                  :underline="false"
                  @click.stop="handleClick('edit', scope.row)"
                >
                  编辑
                </el-link>
                <span v-permission="['driverLibraryManagement:driverLibrary:editDriverTemplateFile']">
                  <el-divider direction="vertical"></el-divider>
                </span>
                <el-link
                  v-permission="['driverLibraryManagement:driverLibrary:downloadDriverTemplateFile']"
                  type="primary"
                  :underline="false"
                  @click.stop="handleClick('download', scope.row)"
                >
                  下载
                </el-link>
                <span v-permission="['driverLibraryManagement:driverLibrary:delDriverTemplateFile']">
                  <el-divider direction="vertical"></el-divider>
                </span>

                <el-popconfirm
                  v-permission="['driverLibraryManagement:driverLibrary:delDriverTemplateFile']"
                  title="将永久删除,是否确认删除？"
                  @confirm="handleClick('del', scope.row)"
                >
                  <el-link slot="reference" type="primary" :underline="false" @click.stop>删除</el-link>
                </el-popconfirm>
              </template>
            </el-table-column>
          </el-table>
        </div>
        <div class="rightContent">
          <filePreview
            v-if="currentRow.fileId && codeContent"
            :key="codeContentTimer"
            :content="codeContent"
            :file-type="currentRow.fileType"
          />
        </div>
      </div>
    </div>
    <driverPrgram ref="driverPrgram" @submit="refreshData" />
  </div>
</template>

<script>
import { editFileName, deleteFile, getOneSlaveDriverInfo } from '@/api/project-management'
import driverPrgram from './driverPrgram.vue'
import addDriverFile from './addDriverFile.vue'
import { downLoadFile, fileDownload } from '@/utils/download'
import { checkPermission } from '@/directive/permission/checkPermission.js' // 权限判断指令
import defaultSettings from '@/settings'
import { generateUUID, postMessage, receivedMessage } from '@/utils/index'
import axios from 'axios'
import filePreview from '@/components/filePreview/index'
export default {
  name: 'SlaveChipDriver',
  components: { filePreview, driverPrgram, addDriverFile },
  props: {
    currentProjectData: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    return {
      currentRow: {},
      codeContent: ``,
      codeContentTimer: null,
      diffPage: {},
      downloadFileRequestId: generateUUID(),
      editFileNameRequestId: generateUUID(),
      deleteFileRequestId: generateUUID(),
      readFileRequestId: generateUUID(),
      refreshDriverFileRequestId: generateUUID()
    }
  },

  mounted() {
    receivedMessage(this.dataHandle)
  },
  methods: {
    dataHandle(result) {
      let self = this
      let e = defaultSettings.isWPF ? result : { data: JSON.parse(result) }
      if (e.data.webInfo.requestId === self.downloadFileRequestId) {
        let res = e.data.response
        if (res.success) {
          var bytes = new Uint8Array(
            window
              .atob(res.data)
              .split('')
              .map(function (c) {
                return c.charCodeAt(0)
              })
          )
          res.data = bytes
          fileDownload(res)
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.deleteFileRequestId) {
        if (e.data.response.success) {
          self.refreshDriverFile()
        } else {
          self.$message.error(e.data.response.message)
        }
      } else if (e.data.webInfo.requestId === self.readFileRequestId) {
        if (self.currentRow.fileType === '.pdf') {
          self.codeContent = 'data:application/pdf;base64,' + e.data.response.data
        } else {
          let uint8Array = Uint8Array.from(atob(e.data.response.data), (c) => c.charCodeAt(0))
          let decoder = new TextDecoder()
          let decodedText = decoder.decode(uint8Array)

          // 判断解码后的文本是否包含乱码字符
          const isDecoded = Array.from(decodedText).every((char) => char.charCodeAt(0) !== 65533)
          if (!isDecoded) {
            decoder = new TextDecoder('GBK')
            decodedText = decoder.decode(uint8Array)
          }

          self.codeContent = `${decodedText}`
        }

        self.codeContentTimer = new Date().getTime()
      } else if (e.data.webInfo.requestId === self.refreshDriverFileRequestId) {
        let res = e.data.response
        if (res.success) {
          self.initDriverFile(res)
        } else {
          self.$message.error(res.message)
        }
      } else if (e.data.webInfo.requestId === self.editFileNameRequestId) {
        let res = e.data.response
        if (!res.success) {
          self.$message.error(res.message)
        }
      }
    },
    init(flag) {
      if (flag) {
        let row = this.diffPage[this.currentProjectData.driverLibraryId]
        this.$refs.myTable.setCurrentRow(row)
        this.handleRowClick(row)
      } else {
        if (this.currentProjectData.driverFile.length > 0) {
          this.$refs.myTable.setCurrentRow(this.currentProjectData.driverFile?.[0])
          this.handleRowClick(this.currentProjectData.driverFile?.[0])
        } else {
          this.handleRowClick(this.currentProjectData.driverFile?.[0])
        }
      }
    },
    handleRowClick(row) {
      if (this.currentRow?.fileId === row?.fileId) return
      this.currentRow = row ?? {}
      this.diffPage[this.currentProjectData.driverLibraryId] = this.currentRow
      if (row?.fileId) {
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.readFileRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/preview',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: { filePath: row.path },
            WebInfo: {
              requestId: this.readFileRequestId
            }
          }
          postMessage(message)
        } else {
          axios({
            method: 'get',
            url: process.env.VUE_APP_BASE_API + row.path,
            responseType: 'arraybuffer' // 设置响应类型为 arraybuffer
          }).then((resp) => {
            if (this.currentRow.fileType === '.pdf') {
              this.codeContent = URL.createObjectURL(new Blob([resp.data], { type: 'application/pdf' }))
            } else if (['.h', '.c'].includes(this.currentRow.fileType)) {
              const decoder = new TextDecoder('GBK')
              const text = decoder.decode(resp.data)
              this.codeContent = `${text}`
            } else {
              const decoder = new TextDecoder('utf-8')
              const text = decoder.decode(resp.data)
              this.codeContent = `${text}`
            }
            this.codeContentTimer = new Date().getTime()
          })
        }
      } else {
        this.codeContent = ``
        this.codeContentTimer = new Date().getTime()
      }
    },
    handleClick(name, row) {
      if (name === 'downloadDriveDefinitionFile') {
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.downloadFileRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/download',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: { files: this.currentProjectData.driverDefinitionFiles },
            WebInfo: {
              requestId: this.downloadFileRequestId
            }
          }
          postMessage(message)
        } else {
          downLoadFile(
            process.env.VUE_APP_BASE_API + this.currentProjectData.driverDefinitionFiles?.[0]?.path,
            this.currentProjectData.driverDefinitionFiles?.[0]?.fileName
          )
        }
      } else if (name === 'updateDriveDefinitionFile') {
        this.$refs.driverPrgram.is('edit', {
          chipType: 2,
          driverLibraryId: this.currentProjectData.driverLibraryId,
          historyDriverDefinitionFiles: this.currentProjectData.driverDefinitionFiles.map((item) => {
            return {
              ...item,
              name: item.fileName,
              url: item.path
            }
          }),
          driverDefinitionFiles: []
        })
      } else if (name === 'uploadDriverFile') {
        this.$refs.addDriverFile.is(this.currentProjectData)
      } else if (name === 'edit') {
        if (checkPermission('driverLibraryManagement:driverLibrary:editDriverTemplateFile')) {
          row.editable = true
          this.$nextTick(() => {
            this.$refs['fileName' + row.fileId].focus()
          })
        }
      } else if (name === 'download') {
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.downloadFileRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/download',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: {
              files: [
                {
                  fileName: row.fileName + row.fileType,
                  path: row.path
                }
              ]
            },
            WebInfo: {
              requestId: this.downloadFileRequestId
            }
          }
          postMessage(message)
        } else {
          downLoadFile(process.env.VUE_APP_BASE_API + row.path, row.fileName + row.fileType)
        }
      } else if (name === 'del') {
        this.currentRow = {}
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.deleteFileRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/delete',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: { fileId: row.fileId },
            WebInfo: {
              requestId: this.deleteFileRequestId
            }
          }
          postMessage(message)
        } else {
          deleteFile({ fileId: row.fileId }).then((res) => {
            if (res.success) {
              this.refreshDriverFile()
            } else {
              this.$message.error(res.message)
            }
          })
        }
      } else if (name === 'saveFileName') {
        row.editable = false
        let params = {
          fileId: row.fileId,
          fileName: row.fileName + row.fileType
        }
        if (defaultSettings.isWPF || defaultSettings.isCEF) {
          this.editFileNameRequestId = generateUUID()
          let message = {
            RequestUrl: process.env.VUE_APP_URL + '/files/editName',
            RequestMethod: 'POST',
            Headers: {
              contentType: 'application/json'
            },
            QueryParameter: {},
            RequestBody: params,
            WebInfo: {
              requestId: this.editFileNameRequestId
            }
          }
          postMessage(message)
        } else {
          editFileName(params)
        }
      }
    },
    refreshData() {
      this.$emit('refresh', this.currentProjectData)
    },
    refreshDriverFile() {
      // 刷新驱动模板文件列表
      if (defaultSettings.isWPF || defaultSettings.isCEF) {
        this.refreshDriverFileRequestId = generateUUID()
        let message = {
          RequestUrl: process.env.VUE_APP_URL + '/driverLibrary/getOneSlaveDriverInfo',
          RequestMethod: 'POST',
          Headers: {
            contentType: 'application/json'
          },
          QueryParameter: {},
          RequestBody: { driverLibraryId: this.currentProjectData.driverLibraryId },
          WebInfo: {
            requestId: this.refreshDriverFileRequestId
          }
        }
        postMessage(message)
      } else {
        getOneSlaveDriverInfo({ driverLibraryId: this.currentProjectData.driverLibraryId }).then((res) => {
          this.initDriverFile(res)
        })
      }
    },
    initDriverFile(res) {
      this.currentProjectData.driverFile = res.data.hHeaderFiles
        .concat(res.data.cSourceFiles, res.data.driverDocumentationFiles, res.data.otherDriverFiles)
        .map((item) => {
          return {
            ...item,
            fileName: item.fileName.split('.')[0],
            editable: false
          }
        })
      if (this.currentRow.fileId) {
        let currentRow = this.currentProjectData.driverFile.find((item) => item.fileId === this.currentRow.fileId)
        this.$refs.myTable.setCurrentRow(currentRow)
      } else {
        this.$refs.myTable.setCurrentRow(this.currentProjectData.driverFile?.[0])
        this.handleRowClick(this.currentProjectData.driverFile?.[0])
      }
    }
  }
}
</script>

<style lang="less" scoped>
.driverContent {
  display: flex;
  flex-direction: column;
  height: 100%;
  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    .subTitle {
      font-weight: bold;
    }
  }

  .driverInfo {
    border-bottom: 1px solid #e6e6e6;
    padding-bottom: 22px;
    margin: 0 24px;
    .driverParams {
      margin-top: 14px;
      div:first-of-type {
        margin-bottom: 20px;
      }
    }
  }
  .driverFile {
    margin-top: 20px;
    flex: 1;
    height: auto;
    overflow: hidden;
    .header {
      margin: 0 24px;
    }

    .driverFileContent {
      margin-top: 20px;
      height: calc(100% - 52px);
      display: flex;
      border-top: 1px solid #b9c8dc;
      .leftContent {
        background-color: #f7faff;
        border-right: 1px solid #b9c8dc;

        height: 100%;
        width: 450px;
        /deep/.myTable {
          .el-table__body-wrapper {
            background-color: #f7faff;
          }
          th.el-table__cell {
            background-color: #dcdeec;
          }
          .pointer {
            cursor: pointer;
          }
          .el-input-group__append {
            padding: 0 10px;
          }
        }
      }
      .rightContent {
        flex: 1;
        width: 0;
      }
    }
  }
}
</style>
